import { deepCopy } from "@/package/treeMethods/copy.ts";
import { RouteLocationNormalizedLoaded } from 'vue-router';
import { $_on } from './eventBus';

// 节流
const throttle = function (fn: Function, interval?: number): Function {
  let __self = fn; // 保存需要被延迟执行的函数引用
  let timer: number | undefined = undefined; // 定时器
  let firstTime: boolean = true; // 是否是第一次调用

  return function () {
    const args = arguments,
    // @ts-ignore
      __me = this;

    if (firstTime) { // 如果是第一次调用, 不需要延迟执行
      __self.apply(__me, args);
      return firstTime = false;
    }

    if (timer) { // 如果定时器还在, 说明前一次延迟执行还没有完成
      return false;
    }

    timer = setTimeout(function () {
      clearTimeout(timer);
      timer = undefined;
      __self.apply(__me, args);
    }, interval || 250);
  }
}

// python中的sleep函数(让代码睡一会)
const sleep = (time: number = 250) => new Promise((resolve) => setTimeout(resolve, time));

// 循环调用(轮询)
const recursiveCall = (callback: () => boolean | Promise<any>, time: number) => {
  const timer = setInterval(async () => {
    let flag = callback();
    flag = (flag instanceof Promise) ? await flag : flag;
    if (flag) {
      clearInterval(timer);
    }
  }, (time || 100));
}

const download = (fileName: string, data: any) => {
  const exportData = JSON.stringify({ data });
  const blob = new Blob([exportData]);
  const href = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.download = fileName;
  link.href = href;
  link.click();
  URL.revokeObjectURL(href);
}

const reader = (data: any, cb: Function) => {
  const _reader = new FileReader();
  _reader.readAsText(data);
  _reader.onload = (e) => cb(e?.target?.result);
}

const isObject = (value: any) => Object.prototype.toString.call(value) === '[object Object]';

/* 定义通用的refresh方法 */
const refresh = (name: string, cb: (route?: RouteLocationNormalizedLoaded) => any) => {
  const listener = (route: RouteLocationNormalizedLoaded) => (route.name === name) && cb(route);
  $_on('refresh', listener);
}

/* 捕获同步错误 */
const syncCapture = (cb: Function) => {
  try {
    if (Object.prototype.toString.call(cb) === '[object Function]') {
      cb();
    } else {
      console.error(`捕获同步错误: 参数cb不是函数 -> ${cb.toString()}`);
    }
  } catch (error) {
    console.error('捕获同步错误: ', cb.toString(), error);
  }
}

export {
  throttle,
  sleep,
  recursiveCall,
  download,
  reader,
  isObject,
  deepCopy,
  refresh,
  syncCapture
}